package marlon.smsbatcheditor.activity;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import marlon.smsbatcheditor.Constants;
import marlon.smsbatcheditor.R;
import marlon.smsbatcheditor.db.RuleDAO;
import marlon.smsbatcheditor.model.Rule;
import marlon.smsbatcheditor.model.RuleAction;
import marlon.smsbatcheditor.model.RuleCondition;
import marlon.smsbatcheditor.view.RuleActionView;
import marlon.smsbatcheditor.view.RuleConditionView;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

/**
 * 
 * @author marlonyao<yaolei135@gmail.com>
 */
public class EditRuleActivity extends Activity implements RuleConditionView.OnRemoveListener, RuleActionView.OnRemoveListener, OnClickListener {
	private EditText etName;
	private ViewGroup vgConditions;
	private ViewGroup vgActions;
	private Button btnSave;
	private Button btnCancel;
	
	private long ruleId = -1;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.edit_rule);
	    etName = (EditText) findViewById(R.id.etName);
	    vgConditions = (ViewGroup) findViewById(R.id.vgConditions);
	    vgActions = (ViewGroup) findViewById(R.id.vgActions);
	    
	    btnSave = (Button) findViewById(R.id.btnSave);
	    btnCancel = (Button) findViewById(R.id.btnCancel);
	    btnSave.setOnClickListener(this);
	    btnCancel.setOnClickListener(this);
	    
	    Intent intent = getIntent();
	    if (Intent.ACTION_EDIT.equals(intent.getAction())) { // edit rule
	    	long ruleId = intent.getLongExtra("rule_id", -1L);
	    	Rule rule = new RuleDAO(this).findById(ruleId);
	    	if (rule != null) {
	    		setTitle("Edit Rule \"" + rule.getName() + "\"");
	    		this.ruleId = ruleId;
	    		
	    		etName.setText(rule.getName());
	    		for (Iterator<RuleCondition> itor = rule.getConditions(); itor.hasNext();) {
	    			addRuleCondition(itor.next());
	    		}
	    		for (Iterator<RuleAction> itor = rule.getActions(); itor.hasNext();) {
	    			addRuleAction(itor.next());
	    		}
	    	}
	    }
	    if (this.ruleId == -1) {		// add rule
	    	setTitle("Create Rule");
	    	addRuleCondition(null);
	    	addRuleAction(null);
	    }
	}
	
	private RuleConditionView addRuleCondition(RuleCondition cond) {
		RuleConditionView v = new RuleConditionView(cond, this);
		v.setOnRemoveListener(this);
		vgConditions.addView(v);
		return v;
	}
	
	private RuleActionView addRuleAction(RuleAction action) {
		RuleActionView v = new RuleActionView(action, this);
		v.setOnRemoveListener(this);
		vgActions.addView(v);
		return v;
	}
	
	public int getConditionCount() {
		int count = 0;
		for (int i = 0; i < vgConditions.getChildCount(); i++) {
			View v = vgConditions.getChildAt(i);
			if (v instanceof RuleConditionView)
				count++;
		}
		return count;
	}
	
	public List<RuleConditionView> getConditionViews() {
		List<RuleConditionView> result = new ArrayList<RuleConditionView>();
		for (int i = 0; i < vgConditions.getChildCount(); i++) {
			View v = vgConditions.getChildAt(i);
			if (v instanceof RuleConditionView) {
				RuleConditionView cv = (RuleConditionView) v;
				result.add(cv);
			}
		}
		return result;
	}
	
	public int getActionCount() {
		int count = 0;
		for (int i = 0; i < vgActions.getChildCount(); i++) {
			View v = vgActions.getChildAt(i);
			if (v instanceof RuleActionView)
				count++;
		}
		return count;
	}
	
	public List<RuleActionView> getActionViews() {
		List<RuleActionView> result = new ArrayList<RuleActionView>();
		for (int i = 0; i < vgActions.getChildCount(); i++) {
			View v = vgActions.getChildAt(i);
			if (v instanceof RuleActionView)
				result.add((RuleActionView) v);
		}
		return result;
	}
	
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	super.onCreateOptionsMenu(menu);
    	menu.add(0, Constants.MENU_ADD_CONDITION, Menu.NONE, "Add Condition");
    	menu.add(0, Constants.MENU_ADD_ACTION, Menu.NONE, "Add Action");
    	return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case Constants.MENU_ADD_CONDITION:
		    addRuleCondition(null);
        	return true;
        case Constants.MENU_ADD_ACTION:
		    addRuleAction(null);
        	return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }
    
	@Override
	public void onRemove(RuleConditionView view) {
		if (getConditionCount() <= 1) {
			Toast.makeText(this, "Can not remove last condition", Toast.LENGTH_SHORT).show();
		} else {
			vgConditions.removeView(view);
		}
	}

	@Override
	public void onRemove(RuleActionView view) {
		if (getActionCount() <= 1) {
			Toast.makeText(this, "Can not remove last action", Toast.LENGTH_SHORT).show();
		} else {
			vgActions.removeView(view);
		}
	}

	@Override
	public void onClick(View v) {
		if (v == btnSave) {
			if (saveRule()) {
				setResult(RESULT_OK);
				finish();
			}
		} else if (v == btnCancel) {
			setResult(RESULT_CANCELED);
			finish();
		}
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)  {
	    if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
			if (saveRule()) {
				setResult(RESULT_OK);
				finish();
			}
	        return true;
	    }
	    return super.onKeyDown(keyCode, event);
	}

	private boolean saveRule() {
		if (validateRule()) {
			Rule rule = new Rule(ruleId, etName.getText().toString());
			for (RuleConditionView v : getConditionViews()) {
				rule.addCondition(v.getRuleCondition());
			}
			for (RuleActionView v : getActionViews()) {
				rule.addAction(v.getRuleAction());
			}
			new RuleDAO(this).save(rule);
			
			Toast.makeText(this, "Rule saved.", Toast.LENGTH_SHORT).show();
			return true;
		}
		return false;
	}

	
	private boolean validateRule() {
		String ruleName = etName.getText().toString();
		if (ruleName.length() == 0) {
			Toast.makeText(this, "Must specify rule name", Toast.LENGTH_SHORT).show();
			return false;
		}
		// check conditions
		for (RuleConditionView v : getConditionViews()) {
			if (v.validate() == false) {
				return false;
			}
		}
		// check actions
		for (RuleActionView v : getActionViews()) {
			if (v.validate() == false)
				return false;
		}
		return true;
	}
}
